package cn.unknowpupil.init.utils;


import cn.hutool.core.text.StrFormatter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description: 描述。</br>
 * <p>
 *
 * </p>
 * @Author: <a> w10g </a>
 * @Since: 2020/7/5 21:44
 */

public class StringUtils extends org.apache.commons.lang3.StringUtils {


    private static final Logger log = LoggerFactory.getLogger(StringUtils.class);

    private static final char SEPARATOR = '_';


    /**
     * 功能：格式化空字符串
     *
     * @param str
     * @return String
     */
    public static String formatNull(Object str) {
        return null == str || "null".equals(str) ? "" : str.toString();
    }

    public static String subStr(String str) {
        if (str.startsWith("[")) {
            str = str.substring(1);
        }
        if (str.endsWith("]")) {
            str = str.substring(0, str.length() - 1);
        }
        return str;
    }

    /**
     * 字符串 转 字节数组
     *
     * @param str
     */
    public static char[] string2Char(String str) {
        //通过toCharArray方法
        return str.toCharArray();
    }

    /**
     * 字节数组转字符串
     *
     * @param chars
     */
    public static String char2tring(char[] chars) {

        //通过String构造函数
        String str1 = new String(chars);
        //通过String类型转换，实际也是new String(char[])
        return String.valueOf(chars);
    }

    /**
     * 数组转list
     */
    public static List<Character> array2List(Character[] chars) {

        //通过Collections工具类
        List<Character> list = new ArrayList<>();
        Collections.addAll(list, chars);
        return list;
    }

    /**
     * 原理就是首先将String转换成String[]数组，
     * 再通过工具类转换为List
     *
     * @param str
     */
    public static List<String> string2List(String str) {
        //方式一
        //str.split()返回一个String[]数组
        List<String> list = Arrays.asList(str.split(""));
        return list;
    }

    /**
     *
     */
    /**
     * List to String
     *
     * @param list
     * @return
     */
    public static String list2String(List<String> list) {
        String str = String.join("", list);
        return str;
    }


    /**
     * List to Set
     *
     * @param list
     * @return
     */
    public static Set<String> list2Set(List<String> list) {
        //直接构造函数即可
        Set<String> set = new HashSet<>(list);
        return set;
    }

    /**
     * Set to List
     *
     * @param set
     */
    public static void set2List(Set<String> set) {
        //直接构造函数即可
        List<String> list = new ArrayList<>(set);
    }

    /**
     * String 2 Set
     *
     * @param str
     * @return
     */
    public static Set<String> string2Set(String str) {

        String[] strings = str.split("");
        Set<String> set = new HashSet<>();
        Collections.addAll(set, strings);
        return set;
    }

    /**
     * Set 2 String
     *
     * @param set
     * @return
     */
    public static String set2String(Set<String> set) {
        return String.join("", set);
    }

    /**
     * array 2 Set
     *
     * @param chars
     */
    public static Set<Character> array2Set(Character[] chars) {
        Set<Character> set = new HashSet<>();
        Collections.addAll(set, chars);
        return set;
    }

    /**
     * Set 2 Array
     *
     * @param set
     * @return
     */
    public static Character[] set2Array(Set<Character> set) {
        Character[] chars = set.toArray(new Character[set.size()]);
        return chars;
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase(" hello_world ") == "helloWorld"
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     * toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCamelCase(String s) {
        if (s == null) {
            return null;
        }

        s = s.toLowerCase();

        StringBuilder sb = new StringBuilder(s.length());
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            if (c == SEPARATOR) {
                upperCase = true;
            } else if (upperCase) {
                sb.append(Character.toUpperCase(c));
                upperCase = false;
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase(" hello_world ") == "helloWorld"
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     * toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCapitalizeCamelCase(String s) {
        if (s == null) {
            return null;
        }
        s = toCamelCase(s);
        return s.substring(0, 1).toUpperCase() + s.substring(1);
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase(" hello_world ") == "helloWorld"
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     * toUnderScoreCase("helloWorld") = "hello_world"
     */
    static String toUnderScoreCase(String s) {
        if (s == null) {
            return null;
        }

        StringBuilder sb = new StringBuilder();
        boolean upperCase = false;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);

            boolean nextUpperCase = true;

            if (i < (s.length() - 1)) {
                nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
            }

            if ((i > 0) && Character.isUpperCase(c)) {
                if (!upperCase || !nextUpperCase) {
                    sb.append(SEPARATOR);
                }
                upperCase = true;
            } else {
                upperCase = false;
            }

            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }


    /**
     * 验证身份证后四位是否是数字，最后一位可能是X
     *
     * @param str
     * @return
     */
    public static boolean isNumericZidai(String str) {
        for (int i = 0; i < str.length() - 1; i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        /**
         * 由于考虑到省份后四位最后以为可能是X所有做一下判断
         */
        char c = str.charAt(str.length() - 1);
        if ((c != 'x' && c != 'X') && (c >= '9' || c <= '0')) {
            return false;
        }

        return true;
    }

    /**
     * 是否包含字符串
     *
     * @param str  验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs) {
        if (str != null && strs != null) {
            for (String s : strs) {
                if (str.equalsIgnoreCase(trim(s))) {
                    return true;
                }
            }
        }
        return false;
    }

    public static String getBlock(Object msg) {
        if (msg == null) {
            msg = "";
        }
        return "[" + msg.toString() + "]";
    }

    /**
     * * 判断一个对象数组是否为空
     *
     * @param objects 要判断的对象数组
     *                * @return true：为空 false：非空
     */
    public static boolean isEmpty(Object[] objects) {
        return isNull(objects) || (objects.length == 0);
    }


    /**
     * 格式化文本, {} 表示占位符<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可，如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例：<br>
     * 通常使用：format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}： format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\： format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     *
     * @param template 文本模板，被替换的部分用 {} 表示
     * @param params   参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... params) {
        if (isEmpty(params) || isEmpty(template)) {
            return template;
        }
        return StrFormatter.format(template, params);
    }

    /**
     * * 判断一个对象是否为空
     *
     * @param object Object
     * @return true：为空 false：非空
     */
    public static boolean isNull(Object object) {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     *
     * @param object Object
     * @return true：非空 false：空
     */
    public static boolean isNotNull(Object object) {
        return !isNull(object);
    }

    public static boolean isNotEmpties( Collection<?> coll) {
        return !isEmpty(coll);
    }
    public static boolean isEmpty(Collection<?> coll)
    {
        return isNull(coll) || coll.isEmpty();
    }

    @SuppressWarnings("unchecked")
    public static <T> T cast(Object obj)
    {
        return (T) obj;
    }

    public static boolean isEmail(String string) {
        if (string == null) {
            return false;
        }
        String regEx1 = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
        Pattern p;
        Matcher m;
        p = Pattern.compile(regEx1);
        m = p.matcher(string);
        return m.matches();

    }

    public static <T> List<T> castList(Object obj, Class<T> clazz)
    {
        List<T> result = new ArrayList<T>();
        if(obj instanceof List<?>)
        {
            for (Object o : (List<?>) obj)
            {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }

    public static boolean isNotEmpty(String str)
    {
        return !isEmpty(str);
    }

    /**
     * * 判断一个Map是否为空
     *
     * @param map 要判断的Map
     * @return true：非空 false：空
     */
    public static boolean isNotEmpty(Map<?, ?> map)
    {
        return !isEmpty(map);
    }

    /**
     * * 判断一个Map是否为空
     *
     * @param map 要判断的Map
     * @return true：为空 false：非空
     */
    public static boolean isEmpty(Map<?, ?> map)
    {
        return isNull(map) || map.isEmpty();
    }

    public static String convertToCamelCase(String name) {
        StringBuilder result = new StringBuilder();
        // 快速检查
        if (name == null || name.isEmpty())
        {
            // 没必要转换
            return "";
        }
        else if (!name.contains("_"))
        {
            // 不含下划线，仅将首字母大写
            return name.substring(0, 1).toUpperCase() + name.substring(1);
        }
        // 用下划线将原始字符串分割
        String[] camels = name.split("_");
        for (String camel : camels)
        {
            // 跳过原始字符串中开头、结尾的下换线或双重下划线
            if (camel.isEmpty())
            {
                continue;
            }
            // 首字母大写
            result.append(camel.substring(0, 1).toUpperCase());
            result.append(camel.substring(1).toLowerCase());
        }
        return result.toString();
    }

    /**
     * * 判断一个Collection是否非空，包含List，Set，Queue
     *
     * @param coll 要判断的Collection
     * @return true：非空 false：空
     */
    public static boolean isNotEmpty(Collection<?> coll)
    {
        return !isEmpty(coll);
    }
}